ラズピコでSPI Flashの読み書き
利用するフラッシュメモリ
16MB QSPI/SPIフラッシュメモリブレークアウト基板(W25Q128JV)
128 MbitのQSPI/SPI接続シリアルフラッシュメモリであるW25Q128JVSSIQを使いやすい300 mil幅DIP-8形状に変換したブレークアウト基板です。
チップ
W25Q128JVSSIQ
データシート
チュートリアル
ピン配置
1: CS
2: IO1 (MISO)
3: IO2(Write Protect Input ... Active Low)
4: GND
5: 3.3V
6: IO3: (Hold Input ... Allows the device to be paused while it is actively selected)
7: CLK
8: IO0 (MOSI)
https://gyazo.com/1ba15cf4659e8160560b27e6ce6fc51b
ラズピコのピン
PICO_DEFAULT_SPI_SCK_PIN 18 → CLK(7ピン)へ
PICO_DEFAULT_SPI_TX_PIN 19 → IO0/MOSI(8ピン)へ
PICO_DEFAULT_SPI_RX_PIN 16 → IO1/MISO(2ピン)へ
PICO_DEFAULT_SPI_CSN_PIN 17 → CS(1ピン)へ
(IO2はLOWにすると書き込み制限されそうなので、HIGHにしておくと良さそう)
(IO3は...LOWでもいいかな...)
code:c
// --- SPI ---
#define PICO_DEFAULT_SPI_SCK_PIN 18 → CLK(7ピン)へ #define PICO_DEFAULT_SPI_TX_PIN 19 → IO0/MOSI(8ピン)へ #define PICO_DEFAULT_SPI_RX_PIN 16 → IO1/MISO(2ピン)へ #define PICO_DEFAULT_SPI_CSN_PIN 17 → CS(1ピン)へ https://gyazo.com/2eda35e7caafea77d8e8ad1b39bf7cf8
https://gyazo.com/8094a71edb8be2b136f605fbfcb94403
PICO_DEFAULT_SPI_SCK_PIN 18 → CLK(7ピン)へ
PICO_DEFAULT_SPI_TX_PIN 19 → IO0/MOSI(8ピン)へ
PICO_DEFAULT_SPI_RX_PIN 16 → IO1/MISO(2ピン)へ
PICO_DEFAULT_SPI_CSN_PIN 17 → CS(1ピン)へ
(IO2はLOWにすると書き込み制限されそうなので、HIGHにしておくと良さそう)
(IO3は...LOWでもいいかな...)
PlatformIOへライブラリを追加
以下を参考に Adafruit SPIFlash を追加する
platformio.ini に lib_deps を追加
code:diff
diff --git a/platformio.ini b/platformio.ini
index 824ceec..7f402b2 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -9,6 +9,9 @@
board = pico
framework = arduino
board_build.core = earlephilhower
+lib_deps =
+ adafruit/Adafruit SPIFlash@^4.2.1
以下のソースを良さげな場所に配置。
オリジナルは以下にあります
code:flash_config.h
/*
* The MIT License (MIT)
*
* Copyright (c) 2022 Ha Thach (tinyusb.org) for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Un-comment to run example with custom SPI and SS e.g with FRAM breakout
#if defined(CUSTOM_CS) && defined(CUSTOM_SPI) Adafruit_FlashTransport_SPI flashTransport(CUSTOM_CS, CUSTOM_SPI);
#elif defined(ARDUINO_ARCH_ESP32) // ESP32 use same flash device that store code for file system.
// SPIFlash will parse partition.cvs to detect FATFS partition to use
Adafruit_FlashTransport_ESP32 flashTransport;
#elif defined(ARDUINO_ARCH_RP2040) // RP2040 use same flash device that store code for file system. Therefore we
// only need to specify start address and size (no need SPI or SS)
// By default (start=0, size=0), values that match file system setting in
// 'Tools->Flash Size' menu selection will be used.
Adafruit_FlashTransport_RP2040 flashTransport;
// To be compatible with CircuitPython partition scheme (start_address = 1 MB,
// size = total flash - 1 MB) use const value (CPY_START_ADDR, CPY_SIZE) or
// subclass Adafruit_FlashTransport_RP2040_CPY. Un-comment either of the
// following line:
// Adafruit_FlashTransport_RP2040
// flashTransport(Adafruit_FlashTransport_RP2040::CPY_START_ADDR,
// Adafruit_FlashTransport_RP2040::CPY_SIZE);
// Adafruit_FlashTransport_RP2040_CPY flashTransport;
// On-board external flash (QSPI or SPI) macros should already
// defined in your board variant if supported
// - EXTERNAL_FLASH_USE_QSPI
// - EXTERNAL_FLASH_USE_CS/EXTERNAL_FLASH_USE_SPI
#if defined(EXTERNAL_FLASH_USE_QSPI) Adafruit_FlashTransport_QSPI flashTransport;
#elif defined(EXTERNAL_FLASH_USE_SPI) Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS,
EXTERNAL_FLASH_USE_SPI);
// Use stand SPI/SS for avr port.
// Note cache will be disable due to lack of memory.
Adafruit_FlashTransport_SPI flashTransport(SS, SPI);
#error No (Q)SPI flash are defined for your board ! code:main.cpp
/*
SD card read/write
This example shows how to read and write data to and from an SD card file
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
created Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
// for flashTransport definition
Adafruit_SPIFlash flash(&flashTransport);
// file system object from SdFat
FatVolume fatfs;
File32 myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
delay(
10); // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Initializing Filesystem on external flash...");
// Init external flash
flash.begin();
// Open file system on the flash
if (!fatfs.begin(&flash)) {
Serial.println("Error: filesystem is not existed. Please try SdFat_format "
"example to make one.");
while (1) {
yield();
delay(1);
}
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = fatfs.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
// re-open the file for reading:
myFile = fatfs.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop() {
// nothing happens after setup
}
動かないのはこれが原因かもしれない
再チャレンジ
SPIのピンを以下のように指定して、
code:diff
void setup() {
SPI.setRX(0);
SPI.setCS(1);
SPI.setSCK(2);
SPI.setTX(3);
以下のように配線した
SPI.setRX(0) → 2番ピン(IO1 / MISO)
SPI.setCS(1) → 1番ピン(CS)
SPI.setSCK(2) → 7番ピン(CLK)
SPI.setTX(3) → 8番ピン(IO0 / MOSI)
1ピン配置
1: CS
2: IO1 (MISO)
3: IO2(Write Protect Input ... Active Low)
4: GND
5: 3.3V
6: IO3: (Hold Input ... Allows the device to be paused while it is actively selected)
7: CLK
8: IO0 (MOSI)
https://gyazo.com/1ba15cf4659e8160560b27e6ce6fc51b
うまく信号を送れていないような...